/******************************************************************************
//             INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2000-2001 Intel Corporation. All Rights Reserved.
//
//  Description:
//      Intel(R) JPEG library for X platform 
//
********************************************************************************/
#include "_ijx.h"


#define MAKE_MARKER_2B(ptr, marker)             \
    *ptr++ = (Ipp8u)0xff;                       \
    *ptr++ = (Ipp8u)(marker); 
/*
#define MAKE_VERSION_2B(ptr, version)           \
    *ptr++ = (Ipp8u)((version>>8)&0xff);        \
    *ptr++ = (Ipp8u)(version&0xff);
*/
#define MAKE_INT32_4B(ptr, value)	            \
    {                                           \
        register int nTemp=(value);             \
        *ptr++ = (Ipp8u)((nTemp >> 24) & 0xff); \
        *ptr++ = (Ipp8u)((nTemp >> 16) & 0xff); \
        *ptr++ = (Ipp8u)((nTemp >> 8) & 0xff);  \
        *ptr++ = (Ipp8u)(nTemp & 0xff);         \
    }

#define MAKE_INT16_2B(ptr, value)	            \
    {                                           \
        register int nTemp=(value);             \
        *ptr++ = (Ipp8u)((nTemp >> 8) & 0xff);  \
        *ptr++ = (Ipp8u)(nTemp & 0xff);         \
    }

#define MAKE_INT8_1B(ptr, value)                \
        *ptr++ = (Ipp8u)(value);   

extern const Ipp8u _nIZigZagIndex[64];

/******************************************************************************
// Name:            ijWrite_Marker
// Description:     Wrtie a JPEG marker into code stream
// Input Arguments:
//          marker: Specifies the JPEG marker.
// Output Arguments:
//         pStream: Points to IJBITTREAMSTATE data structure.
//                  
******************************************************************************/
IJXRESULT ijWrite_Marker(Ipp8u marker, IJBITTREAMSTATE *pStream)
{
    Ipp8u data[3];
    Ipp8u *ptr=data;
    IJXRESULT rtCode;

    MAKE_MARKER_2B(ptr, marker)
    rtCode=ijWriteStreamBytes(data, 2, pStream);
    return rtCode;
}


/******************************************************************************
// Name:            ijWrite_COM
// Description:     Wrtie comments into JPEG code stream
// Input Arguments:
//        pSrcData: Points to the buffer that defined comments data.
//            nLen: Specifies comments data buffer length.
// Output Arguments:
//         pStream: Points to IJBITTREAMSTATE data structure.
//                  
//                     
//                  
******************************************************************************/
IJXRESULT ijWrite_COM(char *pSrcData, int nLen, IJBITTREAMSTATE *pStream)
{
    /*
    // Length of COM block	(2 bytes)
    // COM Data             (Variable length) 
    */

    Ipp8u data[10];
    Ipp8u *ptr=data;
    IJXRESULT rtCode;

    if (NULL==pSrcData || 0>=nLen){
        return IJX_RTCODE_OK;
    }

    MAKE_MARKER_2B(ptr, IJX_MARKER_COM);
    MAKE_INT16_2B(ptr, nLen+2);

    rtCode=ijWriteStreamBytes(data, 4, pStream);

    if( !IJX_SUCCEEDED(rtCode) ){
        return rtCode; 
    }

    rtCode=ijWriteStreamBytes(pSrcData, nLen, pStream);

    return rtCode; 
} 

/******************************************************************************
// Name:            ijWrite_APP0_JFIF
// Description:     Write JFIF header into code stream
// Input Arguments:
//           units: Specifies the data unit see below.
//       nXDensity: Specifies image density in horizontal.
//       nYDensity: Specifies image density in vertical.
//          pThumb: Reserved 
// Output Arguments:
//         pStream: Points to IJBITTREAMSTATE data structure.
// Returns:          
//                     
//                  
******************************************************************************/
IJXRESULT ijWrite_APP0_JFIF( Ipp8u units,
                             Ipp32u nXDensity,
                             Ipp32u nYDensity,
                             Ipp16u nVersion,
                             IJTHUMBSPEC  *pThumb,
                             IJBITTREAMSTATE    *pStream)
{
    /*
    // Length of APP0 block	(2 bytes)
    // Block ID			    (5 bytes - ASCII "JFIF\0")
    // Version Major, Minor	(2 bytes - 0x01, 0x01)
    // Units			    (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
    // Xdpu			        (2 bytes - dots per unit horizontal)
    // Ydpu			        (2 bytes - dots per unit vertical)
    // Thumbnail X size		(1 byte)
    // Thumbnail Y size		(1 byte)
    */

    int    len;
    Ipp8u   data[20];
    Ipp8u*  ptr=data;
    IJXRESULT rtCode;

    len = 2 + 5 + 2 + 1 + 2 + 2 + 1 + 1;

    MAKE_MARKER_2B(ptr, IJX_MARKER_APP0);
    MAKE_INT16_2B(ptr,  len);

    /* JFIF\0 */
    MAKE_INT8_1B(ptr, 'J');
    MAKE_INT8_1B(ptr, 'F');
    MAKE_INT8_1B(ptr, 'I');
    MAKE_INT8_1B(ptr, 'F');
    MAKE_INT8_1B(ptr,  0);


    // version
    MAKE_INT16_2B(ptr, nVersion);

    // units
    MAKE_INT8_1B(ptr,  units);

    // aspect ratio
    MAKE_INT16_2B(ptr, nXDensity);
    MAKE_INT16_2B(ptr, nYDensity);

    len=16;

    // thumbnails dimensions
    if( NULL!=pThumb ){
        MAKE_INT8_1B(ptr,  0);
        MAKE_INT8_1B(ptr,  0);
        len+=2;
        rtCode=ijWriteStreamBytes(data, len, pStream);
    } else {
        MAKE_INT8_1B(ptr,  0);
        MAKE_INT8_1B(ptr,  0);
        len+=2;
        rtCode=ijWriteStreamBytes(data, len, pStream);
    }


    return rtCode; 
} 

/******************************************************************************
// Name:            ijWrite_APP0_JFXX
// Description:     Write JFXX header into code stream
// Input Arguments:
//          pThumb: Reserved 
// Output Arguments:
//         pStream: Points to IJBITTREAMSTATE data structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijWrite_APP0_JFXX( IJTHUMBSPEC  *pThumb,
                             IJBITTREAMSTATE    *pStream)
{
    /*
    // Length of APP0 block	(2 bytes)
    // Block ID			    (5 bytes - ASCII "JFXX\0")
    // Extension Code		(1 byte) 
    //                        0x10 = Thumbnail in JPEG;
    //                        0x11 = Thumbnail in 1byte/pixel; 
    //                        0x13 = Thumbnail in 3bytes/pixel)
    // Thumbnail Data       (Variable length) 
    */

    int    len;
    Ipp8u   data[20];
    Ipp8u*  ptr=data;
    IJXRESULT rtCode;

    len = 2 + 5 + 1;

    MAKE_MARKER_2B(ptr, IJX_MARKER_APP0);
    MAKE_INT16_2B(ptr,  len);

    /* JFXX\0 */
    MAKE_INT8_1B(ptr, 'J');
    MAKE_INT8_1B(ptr, 'F');
    MAKE_INT8_1B(ptr, 'X');
    MAKE_INT8_1B(ptr, 'X');
    MAKE_INT8_1B(ptr,  0);

    rtCode=ijWriteStreamBytes(data, len+2, pStream);

    pThumb->nWidth=0;
    pThumb->nHeight=0;

    return rtCode; 
} 

/******************************************************************************
// Name:            ijWrite_APP0_IJXM
// Description:     Write Motion-JPEG header into code stream
// Input Arguments:
//    nJPEGCodeMode: JPEG mode, see below.
//       pImageSpec: Points to IIPIMAGESPEC data structure.
//        pWaveSpec: Points to IWPWAVESPEC data structure.
//      pMotionSpec: Points to IJMOTIONSPEC data structure.
// Output Arguments:
//         pStream:  Points to IJBITTREAMSTATE data structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijWrite_APP0_IJXM( Ipp32u nJPEGCodeMode,
                             const  IIPIMAGESPEC *pImageSpec,
                             const  IWPWAVESPEC  *pWaveSpec,
                             const  IJMOTIONSPEC *pMotionSpec,
                             IJBITTREAMSTATE    *pStream)
{
    /*
    // Length of APP0 block	(2 bytes)
    // IJXM Indentifier     (5 Bytes: "IJXM\0")
    //-----------------------------------------------7Bytes----------
    // nCodeMode;           (4bytes: Still|Motion)
    // nNumComponents;      (1bytes)
    // nMFrameWidth;        (2bytes)
    // nMFrameHeight;       (2bytes)
    // nMRate               (2Bytes)
    // nMFrameRSTInterval;  (2bytes)
    // nMFrameCount;        (4bytes)
    //-----------------------------------------------17Bytes---------
    // nWaveMode            (4Bytes) 
    // nWaveChannels;       (1byte)
    // nWaveSamplesPerSec;  (4Bytes)
    // nAvgBytesPerSec;     (4Bytes)
    // nWaveBlockAlign;     (4Bytes)
    // nWaveBitsPerSample;  (2Bytes)
    //-----------------------------------------------19Bytes---------
    */

    int    len;
    Ipp8u   data[4+24+19];
    Ipp8u*  ptr=data;
    IJXRESULT rtCode;

    len = (24+19);

    MAKE_MARKER_2B(ptr, IJX_MARKER_APP0);
    MAKE_INT16_2B(ptr,  len);

    /* IJXM\0 */
    MAKE_INT8_1B(ptr, 'I');
    MAKE_INT8_1B(ptr, 'J');
    MAKE_INT8_1B(ptr, 'X');
    MAKE_INT8_1B(ptr, 'M');
    MAKE_INT8_1B(ptr,  0);

    /*------------------ Video --------------------*/
    /* nCodeMode */
    MAKE_INT32_4B(ptr, nJPEGCodeMode);

    /* nNumComponents */
    MAKE_INT8_1B(ptr,  pImageSpec->nNumComponent);
    /* nMFrameWidth */
    MAKE_INT16_2B(ptr, pImageSpec->nWidth);
    /* nMFrameHeight */
    MAKE_INT16_2B(ptr, pImageSpec->nHeight);
    /* nMRate */
    MAKE_INT16_2B(ptr, pMotionSpec->nRate);
    /* nMFrameRSTInterval */
    MAKE_INT16_2B(ptr, pMotionSpec->nFrameRSTInterval);
    /* nMFrameCount */
    MAKE_INT32_4B(ptr, pMotionSpec->nFrameCount);

    /*------------------ Wave --------------------*/

    /* nWaveMode */
    MAKE_INT32_4B(ptr, pWaveSpec->nCodeMode);

    /* nWaveChannels */
    MAKE_INT8_1B(ptr, pWaveSpec->nChannels);
    /* nWaveSamplesPerSec */
    MAKE_INT32_4B(ptr, pWaveSpec->nSamplesPerSec);
    /* nAvgBytesPerSec */
    MAKE_INT32_4B(ptr, pWaveSpec->nAvgBytesPerSec);
    /* nWaveBlockAlign */
    MAKE_INT32_4B(ptr, pWaveSpec->nBlockAlign);
    /* nWaveBitsPerSample */
    MAKE_INT16_2B(ptr, pWaveSpec->nBitsPerSample);

    rtCode=ijWriteStreamBytes(data, len+2, pStream);

    return rtCode; 
}
 
/******************************************************************************
// Name:            ijWrite_APP14
// Description:     Write APP14 marker
// Input Arguments:
//                  See below              
// Output Arguments:
//         pStream: Points to IJBITTREAMSTATE data structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijWrite_APP14( Ipp16u nVersion,
                         Ipp32u nFlags0,
                         Ipp32u nFlags1,
                         int  nClrTransform,
                         IJBITTREAMSTATE *pStream)
{
    /*
    // Length of APP14 block	(2 bytes)
    // Block ID			        (5 bytes - ASCII "Adobe")
    // Version Number		    (2 bytes - currently 100)
    // Flags0			        (2 bytes - currently 0)
    // Flags1			        (2 bytes - currently 0)
    // Color transform		    (1 byte)
    //
    // Although Adobe TN 5116 mentions Version = 101, all the Adobe files
    // now in circulation seem to use Version = 100, so that's what we write.
    //
    // We write the color transform byte as 1 if the JPEG color space is
    // YCbCr, 2 if it's YCCK, 0 otherwise.  Adobe's definition has to do with
    // whether the encoder performed a transformation, which is pretty useless.
    */
  
    int    len;
    Ipp8u   data[20];
    Ipp8u   *ptr=data;
    IJXRESULT rtCode;

    len=2 + 5 + 2 + 2 + 2 + 1;

    MAKE_MARKER_2B(ptr, IJX_MARKER_APP14);
    MAKE_INT16_2B(ptr,  len);

    /* Adobe\0 */
    MAKE_INT8_1B(ptr,  'A');
    MAKE_INT8_1B(ptr,  'd');
    MAKE_INT8_1B(ptr,  'o');
    MAKE_INT8_1B(ptr,  'b');
    MAKE_INT8_1B(ptr,  'e');

    MAKE_INT16_2B(ptr, nVersion); /* Version */
    MAKE_INT16_2B(ptr, nFlags0);  /* Flags0 */
    MAKE_INT16_2B(ptr, nFlags1);  /* Flags1 */

    MAKE_INT8_1B(ptr, nClrTransform);

    rtCode=ijWriteStreamBytes(data, len+2, pStream);

    return rtCode; 
}

/******************************************************************************
// Name:            ijWrite_DQT
// Description:     
// Input Arguments:
//              See below
// Output Arguments:
//         pStream: Points to IJBITTREAMSTATE data structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijWrite_DQT(  int nIdent, 
                        int nPrecision, 
                        Ipp16u *pTableData, 
                        IJBITTREAMSTATE *pStream )
{
    /*
    // Length of DQT block      (2 bytes)
    // Table precision          (0.5 byte)
    // Table identifier         (0.5 byte)
    // Table values             (n bytes)
    */

    int i;
    int nLen;
    Ipp8u   data[69+64];
    Ipp8u *ptr=data;
    IJXRESULT rtCode;
    const Ipp8u pZagZigIndex[64] =
    {
        0,  1,  8, 16,  9,  2,  3, 10,
        17, 24, 32, 25, 18, 11,  4,  5,
        12, 19, 26, 33, 40, 48, 41, 34,
        27, 20, 13,  6,  7, 14, 21, 28,
        35, 42, 49, 56, 57, 50, 43, 36,
        29, 22, 15, 23, 30, 37, 44, 51,
        58, 59, 52, 45, 38, 31, 39, 46,
        53, 60, 61, 54, 47, 55, 62, 63
    };

    MAKE_MARKER_2B(ptr, IJX_MARKER_DQT);
    

    switch (nPrecision){
        case 8:
            nLen=67;
            MAKE_INT16_2B(ptr, nLen);
            MAKE_INT8_1B(ptr, (nIdent&0x0f));
            for (i=0; i<64; i++){
                *ptr++ = (Ipp8u)pTableData[pZagZigIndex[i]];
            }
            break;
        case 16:
            nLen=67+64;
            MAKE_INT16_2B(ptr, nLen);
            MAKE_INT8_1B(ptr, ( ((Ipp8u)1<<4)+(((Ipp8u)nIdent)&0x0f) ));
            for (i=0; i<64; i++){
                MAKE_INT16_2B(ptr, pTableData[pZagZigIndex[i]]);
            }
            break;
        default:
            return IJX_RTCODE_OK;
    }

    rtCode=ijWriteStreamBytes(data, nLen+2, pStream);

    return rtCode; 
}

/******************************************************************************
// Name:            ijWrite_DHT
// Description:     
// Input Arguments:
//              See below
// Output Arguments:
//         pStream: Points to IJBITTREAMSTATE data structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijWrite_DHT(int nIdent,
                      int nType,
                      Ipp8u *pHuffbits,
                      Ipp8u *pHuffvals,
                      IJBITTREAMSTATE *pStream)
{
    /*
    // Length of DHT block      (2 bytes)
    // Table class              (0.5 byte; 0=DC, 1=AC)
    // Table identifier         (0.5 byte)
    // Number of Huffman codes  (n bytes)
    // Huffman code value       (n bytes)
    */

    int     i;
    int     mt, nLen;
    Ipp8u   data[324];
    Ipp8u   *ptr=data;
    IJXRESULT rtCode;

    MAKE_MARKER_2B(ptr, IJX_MARKER_DHT);

    mt = 0;
    for (i = 0; i < 16; i++){
        mt += pHuffbits[i];
    }

    nLen=2 + 1 + 16 + mt;

    MAKE_INT16_2B(ptr, nLen);
    MAKE_INT8_1B(ptr, ( (((Ipp8u)nType)<<4)+(Ipp8u)(nIdent) ) );

    for (i = 0; i < 16; i++){
        MAKE_INT8_1B(ptr, pHuffbits[i]);
    }
    
    for (i = 0; i < mt; i++){
        MAKE_INT8_1B(ptr, pHuffvals[i]);
    }

    rtCode=ijWriteStreamBytes(data, nLen+2, pStream);

    return rtCode; 
} 

/******************************************************************************
// Name:            ijWrite_DRI
// Description:     
// Input Arguments:
//              See below
// Output Arguments:
//         pStream: Points to IJBITTREAMSTATE data structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijWrite_DRI(int nRstInterval, 
                       IJBITTREAMSTATE *pStream)
{
    /*
    // Length of DRI block      (2 bytes)
    // Restart interval         (2 bytes)
    */

    Ipp8u   data[6];
    Ipp8u*  ptr=data;
    int    nLen;
    IJXRESULT rtCode;

    nLen = 4;

    MAKE_MARKER_2B(ptr, IJX_MARKER_DRI);
    MAKE_INT16_2B(ptr, nLen);
    MAKE_INT16_2B(ptr, nRstInterval);

    rtCode=ijWriteStreamBytes(data, nLen+2, pStream);

    return rtCode; 
}

/******************************************************************************
// Name:            ijWrite_RST
// Description:     
// Input Arguments:
//              See below
// Output Arguments:
//         pStream: Points to IJBITTREAMSTATE data structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijWrite_RST(int nRSTIndex,
                        IJBITTREAMSTATE *pStream)
{
    Ipp8u data[2];
    Ipp8u *ptr=data;
    IJXRESULT rtCode;

    MAKE_MARKER_2B(ptr, IJX_MARKER_RST0+(nRSTIndex&7));
    rtCode=ijWriteStreamBytes(data, 2, pStream);

    return rtCode;
} // EP_Write_RST()


/******************************************************************************
// Name:            ijWrite_SOF
// Description:     
// Input Arguments:
//              See below
// Output Arguments:
//         pStream: Points to IJBITTREAMSTATE data structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijWrite_SOF( IJFRAMESPEC *pFrameSpec,
                       IJCOMPSPEC *pComp,
                       IJBITTREAMSTATE *pStream)
{
    /*
    // Length of SOF block      (2 bytes)
    // Sample precision         (1 byte)
    // Height                   (2 bytes)
    // Width                    (2 bytes)
    // Number of components     (1 byte)
    // Component Info
    //   Component identifier   (1 byte)
    //   H sampling factor      (0.5 byte)
    //   V sampling factor      (0.5 byte)
    //   Q-Table identifier     (1 byte)
    */

    int    i;
    int    nNumComps=pFrameSpec->nNumComps;
    int    nLen = 8 + (nNumComps*3);
    int    nSOF=pFrameSpec->nSOF;
    Ipp8u  data[10 + IJX_MAXCOMPONENT*3];
    Ipp8u  *ptr=data;
    IJXRESULT rtCode;

    MAKE_MARKER_2B(ptr, nSOF);
    MAKE_INT16_2B(ptr, nLen);
    MAKE_INT8_1B(ptr, 8);
    MAKE_INT16_2B(ptr, pFrameSpec->nHeight);
    MAKE_INT16_2B(ptr, pFrameSpec->nWidth);
    MAKE_INT8_1B(ptr, nNumComps);

    for (i=0; i<nNumComps; i++){
        MAKE_INT8_1B(ptr, (i+1));
        MAKE_INT8_1B(ptr, ( (pComp[i].nHSampling<<4)+((pComp[i].nVSampling)&0xff) ) );
        MAKE_INT8_1B(ptr, pComp[i].nQuantTableIndex);
    }

    rtCode=ijWriteStreamBytes(data, nLen+2, pStream);

    return rtCode;
} 

/******************************************************************************
// Name:            ijWrite_SOS
// Description:     
// Input Arguments:
//              See below
// Output Arguments:
//         pStream: Points to IJBITTREAMSTATE data structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijWrite_SOS( IJSCANSPEC *pScanSpec,
                       IJBITTREAMSTATE *pStream)
{
    /*
    // Length of SOS block      (2 bytes)
    // number of Comp in scan   (1 byte)
    // Component Info
    //   Component identifier   (1 byte)
    //   DC-Huff identifier     (0.5 byte)
    //   AC-Huff identifier     (0.5 byte)
    //   Q-Table identifier     (1 byte)
    // Start of spectral        (1 byte)
    // End of spectral          (1 byte)
    // SA-High                  (0.5 byte)
    // SE-Low                   (0.5 byte)
    */

    Ipp8u   data[16];
    Ipp8u*  ptr=data;
    int    nLen;
    int    i;
    int    nNumComps=pScanSpec->nNumComps; 
    IJCOMPSPEC **ppComp;
    IJXRESULT rtCode;

    ppComp=pScanSpec->ppCompSpec;

    nLen = 6 + (2 * nNumComps);

    MAKE_MARKER_2B(ptr, IJX_MARKER_SOS);
    MAKE_INT16_2B(ptr, nLen);
    MAKE_INT8_1B(ptr, nNumComps);

    for (i=0; i<nNumComps; i++){
        MAKE_INT8_1B(ptr, (ppComp[i]->nIdentifier+1));
        MAKE_INT8_1B(ptr, ( (ppComp[i]->nDCHuffTableIndex<<4)+((ppComp[i]->nACHuffTableIndex)&0xff) ) );
    }

    MAKE_INT8_1B(ptr, pScanSpec->ss);
    MAKE_INT8_1B(ptr, pScanSpec->se);
    MAKE_INT8_1B(ptr, ((pScanSpec->ah<<4)+(pScanSpec->al&0x0f)));

    rtCode=ijWriteStreamBytes(data, nLen+2, pStream);  

    return rtCode;
}

/******************************************************************************
// Name:            ijAddWaveStream
// Description:     Add wave stream into main code stream
// Input Arguments:
//   pWaveStreamBuf: Points to wave stream
//      nByteLength: Specifies wave stream in bytes.
// Output Arguments:
//         pStream:  Points to IJBITTREAMSTATE data structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijAddWaveStream(void *pWaveStreamBuf,
                          int  nByteLength,
                          IJBITTREAMSTATE *pStream)
{
    Ipp8u data[10];
    Ipp8u *ptr=data;
    IJXRESULT rtCode;

    
    MAKE_MARKER_2B(ptr, IJX_MARKER_SOFW);
    MAKE_INT16_2B(ptr, nByteLength+2);

    rtCode=ijWriteStreamBytes(data, 4, pStream);
    if (!IJX_SUCCEEDED(rtCode)){
        return rtCode;
    }

    rtCode=ijWriteStreamBytes(pWaveStreamBuf, nByteLength, pStream);
    if (!IJX_SUCCEEDED(rtCode)){
        return rtCode;
    }

    return IJX_RTCODE_OK;
}

/******************************************************************************
// Name:            ijAddTimeStamp
// Description:     Add time stamp into main code stream
// Input Arguments:
//        pTimeSpec: Points to IJTIMESPEC data structure.
// Output Arguments:
//         pStream:  Points to IJBITTREAMSTATE data structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijAddTimeStamp(IJTIMESPEC *pTimeSpec, IJBITTREAMSTATE *pStream)
{
    Ipp8u data[32];
    Ipp8u *ptr=data;
    Ipp8u *ptrLenPos;
    int   nLength;
    IJXRESULT rtCode;
        
    MAKE_MARKER_2B(ptr, IJX_MARKER_SOFT);
    //MAKE_INT16_2B(ptr, 6);
    ptrLenPos=ptr;
    ptr+=2;
    nLength = 2;

    if (IJX_TIME_COUNTER & pTimeSpec->nFlags) {
        MAKE_INT32_4B(ptr, pTimeSpec->nTimeCounter);
        nLength += 4;
    }

    if (IJX_TIME_DATE & pTimeSpec->nFlags) {
        int i;
        for (i=0; i<6; i++) {
            *ptr++=pTimeSpec->nDate[i];
        }
        nLength += 6;
    }

    MAKE_INT16_2B(ptrLenPos, nLength);

    rtCode=ijWriteStreamBytes(data, nLength+2, pStream);
    if (!IJX_SUCCEEDED(rtCode)){
        return rtCode;
    }

    return IJX_RTCODE_OK;
}

/* EOF */
